package com.simonall;

import com.simonall.conf.Propertys;
import com.simonall.enums.ResponseCodeEnum;
import com.simonall.gui.Gui;
import com.simonall.gui.utils.CustomTray;
import com.simonall.listen.I18nListener;
import com.simonall.listen.PropertyListener;
import com.simonall.netty.NettyPipelineInitializer;
import com.simonall.print.PrintHandler;
import com.simonall.print.SimpleDocPrintHandler;
import com.simonall.print.SimpleManualPrintHandler;
import com.simonall.print.SimplePdfPrintHandler;
import com.simonall.utils.BusinessException;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.thread.ThreadUtil;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import javafx.application.Application;

/**
 * 主程序
 * 
 * @author simonall
 */
public class Main {

	// Listener Mount
	static {
		CollUtil.newLinkedList(new PropertyListener(), //
				new I18nListener()) //
				.forEach(listen -> listen.mount());

		// 挂载处理器
		CollUtil.newArrayList(new SimpleDocPrintHandler(), //
				new SimpleManualPrintHandler(), //
				new SimplePdfPrintHandler()) //
				.forEach(it -> PrintHandler.factory.add(it));
	}

	// 服务端
	private static void start() throws BusinessException {
		if (!Propertys.DEFAULT_SERVER_ENABLE) {
			return;
		}
		EventLoopGroup bossGroup = new NioEventLoopGroup();
		EventLoopGroup workerGroup = new NioEventLoopGroup();
		try {
			ServerBootstrap bootstrap = new ServerBootstrap();
			bootstrap.group(bossGroup, workerGroup);
			bootstrap.channel(NioServerSocketChannel.class);
			bootstrap.childHandler(new NettyPipelineInitializer());

			Integer port = Propertys.DEFAULT_SERVER_PORT;
			ChannelFuture future = bootstrap.bind(port).sync();
			if (future.isSuccess()) {
				CustomTray.inform(ResponseCodeEnum.SERVER_START_SUCCESS.getDesc());
				future.channel().closeFuture().sync();
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			bossGroup.shutdownGracefully();
			workerGroup.shutdownGracefully();
		}
	}

	public static void main(String[] args) throws Exception {
		ThreadUtil.execute(() -> start());
		Application.launch(Gui.class, args);
	}

}
